package org.huang.zhen;

import org.apache.log4j.Logger;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class MagicBlockInterface implements GameController.GameChangeListener, KeyListener {
    public static final int BLOCK_PIXEL = 20;
    private static final int GAME_UI_WIDTH = 450;
    private static final int GAME_UI_HEIGHT = 560;
    private JFrame mGameUI;
    private JButton mStartBtn;
    private JButton mPauseBtn;
    private JLabel mScoreLabel;
    private JLabel mLevelLabel;
    private GameMapCanvas mGameMapCanvas;
    private BlockCanvas mBlockCanvas;
    private GameController mGameCtrl;
    private static Logger logger = Logger.getLogger(MagicBlockInterface.class);

    public MagicBlockInterface() {
        mGameCtrl = new GameController(this);
    }

    public void start() {
        mGameUI = new JFrame("MagicBlock");
        JPanel content = new JPanel(null);
        mGameUI.setSize(GAME_UI_WIDTH, GAME_UI_HEIGHT);
        mGameUI.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        mGameMapCanvas = new GameMapCanvas(20, 20);
        content.add(mGameMapCanvas);
        JPanel rightPanel = getRightPanel();
        rightPanel.setBounds(mGameMapCanvas.getWidth() + 20, 20, 150, mGameMapCanvas.getHeight());
        content.add(rightPanel);

        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        int dpi = Toolkit.getDefaultToolkit().getScreenResolution();
        mGameUI.add(content);
        mGameUI.setLocationRelativeTo(null);
        mGameUI.setResizable(false);
        mGameUI.setVisible(true);
        mGameUI.addWindowListener(new WindowAdapter() {
            @Override
            public void windowActivated(WindowEvent e) {//激活窗口时，使窗口获得焦点
                mGameUI.requestFocusInWindow();
            }
        });

        mGameUI.addKeyListener(this);
    }

    private JPanel getRightPanel() {
        JPanel panel = new JPanel(null);
        final int marginSize = 20;
        final int largeMarginSize = 50;
        mBlockCanvas = new BlockCanvas(marginSize, 0);
        panel.add(mBlockCanvas);
        JPanel textArea = initTextArea();
        final int textAreaWidth = 100;
        final int textAreaHeight = 200;
        textArea.setBounds(marginSize, mBlockCanvas.getHeight() + largeMarginSize, textAreaWidth, textAreaHeight);
        panel.add(textArea);

        JPanel btnPanel = initButtons();
        final int btnPanelHeight = 200;
        final int btnPanelY = mBlockCanvas.getHeight() + textAreaHeight + largeMarginSize * 2;
        btnPanel.setBounds(marginSize, btnPanelY, textAreaWidth, btnPanelHeight);
        panel.add(btnPanel);
        return panel;
    }

    private JPanel initTextArea() {
        JPanel rightMidPanel = new JPanel(new GridLayout(2, 2));
        JLabel scoreLabel = new JLabel("Score :");
        mScoreLabel = new JLabel("0");
        mScoreLabel.setEnabled(false);
        rightMidPanel.add(scoreLabel);
        rightMidPanel.add(mScoreLabel);

        JLabel levelLabel = new JLabel("Level :");
        mLevelLabel = new JLabel("1");
        mLevelLabel.setEnabled(false);
        rightMidPanel.add(levelLabel);
        rightMidPanel.add(mLevelLabel);
        return rightMidPanel;
    }

    private JPanel initButtons() {
        JPanel rightBottPanel = new JPanel(null);
        final int btnWidth = 100;
        final int btnHeight = 35;
        mStartBtn = new JButton("Start");
        mStartBtn.setBounds(0, 10, btnWidth, btnHeight);
        mPauseBtn = new JButton("Pause");
        mPauseBtn.setBounds(0, btnHeight + 30, btnWidth, btnHeight);
        rightBottPanel.add(mStartBtn);
        rightBottPanel.add(mPauseBtn);
        mStartBtn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                mGameUI.requestFocusInWindow();
                String text = mStartBtn.getText();
                if (text == "Start") {
                    mGameCtrl.startGame();
                    mStartBtn.setText("Stop");
                } else {
                    mGameCtrl.stopGame();
                    mStartBtn.setText("Start");
                }
            }

            ;
        });

        mPauseBtn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                mGameUI.requestFocusInWindow();
                String text = mPauseBtn.getText();
                if (text == "Pause") {
                    mGameCtrl.pauseGame();
                    mPauseBtn.setText("Resume");
                } else {
                    mGameCtrl.continueGame();
                    mPauseBtn.setText("Pause");
                }
            }
        });
        return rightBottPanel;
    }

    @Override
    public void onGameMapChanged(int[][] map) {
        mGameMapCanvas.refresh(map);
    }

    @Override
    public void onNextBlockChanged(int[][] map) {
        mBlockCanvas.updateBlock(new Block(map));
    }

    @Override
    public void onScoreChanged(final int score) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                mScoreLabel.setText(Integer.toString(score));
            }
        });
    }

    @Override
    public void onLevelChanged(final int level) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                mLevelLabel.setText(Integer.toString(level));
            }
        });
    }

    @Override
    public void keyTyped(KeyEvent e) {

    }

    @Override
    public void keyPressed(KeyEvent e) {
        logger.debug("#" + e.getKeyCode());
        switch (e.getKeyCode()) {
            case 37:
                logger.debug("move to left");
                mGameCtrl.moveBlock2Left();
                break;
            case 38:
                mGameCtrl.rotateBlock();
                break;
            case 39:
                mGameCtrl.moveBlock2Right();
                break;
            case 40:
                mGameCtrl.setAccelerateDown(true);
            default:
                // do nothing.
        }
    }

    @Override
    public void keyReleased(KeyEvent e) {
        logger.debug(e.getKeyCode());
        if (e.getKeyCode() == 40) {
            mGameCtrl.setAccelerateDown(false);
        }
    }

    public static void main(String args[]) {
        new MagicBlockInterface().start();
    }
}
